//
//  CLUtils.cpp
//  PlastilinaCore
//
//  Created by Juan Roberto Cabral Flores on 12/9/12.
//
//
#include <PlastilinaCore/Stable.h>

#include <fstream>
#include <string>

#include <PlastilinaCore/opencl/CLUtils.h>

std::string opencl::loadFromFile(const std::string &filename)
{
	std::string	source;
    std::ifstream file(filename);
	
    std::string line;
    while (file.good()) {
        getline(file, line);
        line.append("\n");
        source.append(line);
    }
    return source;
}

const char* opencl::errorToString(cl_int errorcode)
{
#define CLERRSTR(X) case X: return #X; break
    switch (errorcode) {
        CLERRSTR(CL_SUCCESS);
        CLERRSTR(CL_DEVICE_NOT_FOUND);
        CLERRSTR(CL_DEVICE_NOT_AVAILABLE);
        CLERRSTR(CL_COMPILER_NOT_AVAILABLE);
        CLERRSTR(CL_MEM_OBJECT_ALLOCATION_FAILURE);
        CLERRSTR(CL_OUT_OF_RESOURCES);
        CLERRSTR(CL_OUT_OF_HOST_MEMORY);
        CLERRSTR(CL_PROFILING_INFO_NOT_AVAILABLE);
        CLERRSTR(CL_MEM_COPY_OVERLAP);
        CLERRSTR(CL_IMAGE_FORMAT_MISMATCH);
        CLERRSTR(CL_IMAGE_FORMAT_NOT_SUPPORTED);
        CLERRSTR(CL_BUILD_PROGRAM_FAILURE);
        CLERRSTR(CL_MAP_FAILURE);
        CLERRSTR(CL_MISALIGNED_SUB_BUFFER_OFFSET);
        CLERRSTR(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
        CLERRSTR(CL_COMPILE_PROGRAM_FAILURE);
        CLERRSTR(CL_LINKER_NOT_AVAILABLE);
        CLERRSTR(CL_LINK_PROGRAM_FAILURE);
        CLERRSTR(CL_DEVICE_PARTITION_FAILED);
        CLERRSTR(CL_KERNEL_ARG_INFO_NOT_AVAILABLE);
                    
        CLERRSTR(CL_INVALID_VALUE);
        CLERRSTR(CL_INVALID_DEVICE_TYPE);
        CLERRSTR(CL_INVALID_PLATFORM);
        CLERRSTR(CL_INVALID_DEVICE);
        CLERRSTR(CL_INVALID_CONTEXT);
        CLERRSTR(CL_INVALID_QUEUE_PROPERTIES);
        CLERRSTR(CL_INVALID_COMMAND_QUEUE);
        CLERRSTR(CL_INVALID_HOST_PTR);
        CLERRSTR(CL_INVALID_MEM_OBJECT);
        CLERRSTR(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR);
        CLERRSTR(CL_INVALID_IMAGE_SIZE);
        CLERRSTR(CL_INVALID_SAMPLER);
        CLERRSTR(CL_INVALID_BINARY);
        CLERRSTR(CL_INVALID_BUILD_OPTIONS);
        CLERRSTR(CL_INVALID_PROGRAM);
        CLERRSTR(CL_INVALID_PROGRAM_EXECUTABLE);
        CLERRSTR(CL_INVALID_KERNEL_NAME);
        CLERRSTR(CL_INVALID_KERNEL_DEFINITION);
        CLERRSTR(CL_INVALID_KERNEL);
        CLERRSTR(CL_INVALID_ARG_INDEX);
        CLERRSTR(CL_INVALID_ARG_VALUE);
        CLERRSTR(CL_INVALID_ARG_SIZE);
        CLERRSTR(CL_INVALID_KERNEL_ARGS);
        CLERRSTR(CL_INVALID_WORK_DIMENSION);
        CLERRSTR(CL_INVALID_WORK_GROUP_SIZE);
        CLERRSTR(CL_INVALID_WORK_ITEM_SIZE);
        CLERRSTR(CL_INVALID_GLOBAL_OFFSET);
        CLERRSTR(CL_INVALID_EVENT_WAIT_LIST);
        CLERRSTR(CL_INVALID_EVENT);
        CLERRSTR(CL_INVALID_OPERATION);
        CLERRSTR(CL_INVALID_GL_OBJECT);
        CLERRSTR(CL_INVALID_BUFFER_SIZE);
        CLERRSTR(CL_INVALID_MIP_LEVEL);
        CLERRSTR(CL_INVALID_GLOBAL_WORK_SIZE);
        CLERRSTR(CL_INVALID_PROPERTY);
        CLERRSTR(CL_INVALID_IMAGE_DESCRIPTOR);
        CLERRSTR(CL_INVALID_COMPILER_OPTIONS);
        CLERRSTR(CL_INVALID_LINKER_OPTIONS);
        CLERRSTR(CL_INVALID_DEVICE_PARTITION_COUNT);

        default:
            break;
    }
    return "<UNKNOWN_CODE>";
#undef CLERRSTR
}